home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap20 / Multi1 / Multi1.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  8.9 KB  |  292 lines

  1. /*---------------------------------------
  2.    MULTI1.C -- Multitasking Demo
  3.                (c) Charles Petzold, 1998
  4.   ---------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <math.h>
  8.  
  9. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  10.  
  11. int cyChar ;
  12.  
  13. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  14.                     PSTR szCmdLine, int iCmdShow)
  15. {
  16.      static TCHAR szAppName[] = TEXT ("Multi1") ;
  17.      HWND         hwnd ;
  18.      MSG          msg ;
  19.      WNDCLASS     wndclass ;
  20.      
  21.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  22.      wndclass.lpfnWndProc   = WndProc ;
  23.      wndclass.cbClsExtra    = 0 ;
  24.      wndclass.cbWndExtra    = 0 ;
  25.      wndclass.hInstance     = hInstance ;
  26.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  27.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  28.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  29.      wndclass.lpszMenuName  = NULL ;
  30.      wndclass.lpszClassName = szAppName ;
  31.      
  32.      if (!RegisterClass (&wndclass))
  33.      {
  34.           MessageBox (NULL, TEXT ("This program requires Windows NT!"),
  35.                       szAppName, MB_ICONERROR) ;
  36.           return 0 ;
  37.      }
  38.      
  39.      hwnd = CreateWindow (szAppName, TEXT ("Multitasking Demo"),
  40.                           WS_OVERLAPPEDWINDOW,
  41.                           CW_USEDEFAULT, CW_USEDEFAULT,
  42.                           CW_USEDEFAULT, CW_USEDEFAULT,
  43.                           NULL, NULL, hInstance, NULL) ;
  44.      
  45.      ShowWindow (hwnd, iCmdShow) ;
  46.      UpdateWindow (hwnd) ;
  47.      
  48.      while (GetMessage (&msg, NULL, 0, 0))
  49.      {
  50.           TranslateMessage (&msg) ;
  51.           DispatchMessage (&msg) ;
  52.      }
  53.      return msg.wParam ;
  54. }
  55.  
  56. int CheckBottom (HWND hwnd, int cyClient, int iLine)
  57. {
  58.      if (iLine * cyChar + cyChar > cyClient)
  59.      {
  60.           InvalidateRect (hwnd, NULL, TRUE) ;
  61.           UpdateWindow (hwnd) ;
  62.           iLine = 0 ;
  63.      }
  64.      return iLine ;
  65. }
  66.  
  67. // ------------------------------------------------
  68. // Window 1: Display increasing sequence of numbers
  69. // ------------------------------------------------
  70.  
  71. LRESULT APIENTRY WndProc1 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  72. {
  73.      static int iNum, iLine, cyClient ;
  74.      HDC        hdc ;
  75.      TCHAR      szBuffer[16] ;
  76.      
  77.      switch (message)
  78.      {
  79.      case WM_SIZE:
  80.           cyClient = HIWORD (lParam) ;
  81.           return 0 ;
  82.           
  83.      case WM_TIMER:
  84.           if (iNum < 0)
  85.                iNum = 0 ;
  86.           
  87.           iLine = CheckBottom (hwnd, cyClient, iLine) ;
  88.           hdc = GetDC (hwnd) ;
  89.  
  90.           TextOut (hdc, 0, iLine * cyChar, szBuffer, 
  91.                    wsprintf (szBuffer, TEXT ("%d"), iNum++)) ;
  92.  
  93.           ReleaseDC (hwnd, hdc) ;
  94.           iLine++ ;
  95.           return 0 ;
  96.      }
  97.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  98. }
  99.  
  100. // ------------------------------------------------------
  101. // Window 2: Display increasing sequence of prime numbers
  102. // ------------------------------------------------------
  103.  
  104. LRESULT APIENTRY WndProc2 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  105. {
  106.      static int iNum = 1, iLine, cyClient ;
  107.      HDC        hdc ;
  108.      int        i, iSqrt ;
  109.      TCHAR      szBuffer[16] ;
  110.      
  111.      switch (message)
  112.      {
  113.      case WM_SIZE:
  114.           cyClient = HIWORD (lParam) ;
  115.           return 0 ;
  116.           
  117.      case WM_TIMER:
  118.           do   {
  119.                if (++iNum < 0)
  120.                     iNum = 0 ;
  121.                
  122.                iSqrt = (int) sqrt (iNum) ;
  123.                
  124.                for (i = 2 ; i <= iSqrt ; i++)
  125.                     if (iNum % i == 0)
  126.                          break ;
  127.           }
  128.           while (i <= iSqrt) ;
  129.           
  130.           iLine = CheckBottom (hwnd, cyClient, iLine) ;
  131.           hdc = GetDC (hwnd) ;
  132.  
  133.           TextOut (hdc, 0, iLine * cyChar, szBuffer, 
  134.                    wsprintf (szBuffer, TEXT ("%d"), iNum)) ;
  135.  
  136.           ReleaseDC (hwnd, hdc) ;
  137.           iLine++ ;
  138.           return 0 ;
  139.      }
  140.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  141. }
  142.  
  143. // ----------------------------------------------------------
  144. // Window 3: Display increasing sequence of Fibonacci numbers
  145. // ----------------------------------------------------------
  146.  
  147. LRESULT APIENTRY WndProc3 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  148. {
  149.      static int iNum = 0, iNext = 1, iLine, cyClient ;
  150.      HDC        hdc ;
  151.      int        iTemp ;
  152.      TCHAR      szBuffer[16] ;
  153.      
  154.      switch (message)
  155.      {
  156.      case WM_SIZE:
  157.           cyClient = HIWORD (lParam) ;
  158.           return 0 ;
  159.           
  160.      case WM_TIMER:
  161.           if (iNum < 0)
  162.           {
  163.                iNum  = 0 ;
  164.                iNext = 1 ;
  165.           }
  166.           
  167.           iLine = CheckBottom (hwnd, cyClient, iLine) ;
  168.           hdc = GetDC (hwnd) ;
  169.  
  170.           TextOut (hdc, 0, iLine * cyChar, szBuffer, 
  171.                    wsprintf (szBuffer, TEXT ("%d"), iNum)) ;
  172.  
  173.           ReleaseDC (hwnd, hdc) ;
  174.           iTemp  = iNum ;
  175.           iNum   = iNext ;
  176.           iNext += iTemp ;
  177.           iLine++ ;
  178.           return 0 ;
  179.      }
  180.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  181. }
  182.  
  183. // -----------------------------------------
  184. // Window 4: Display circles of random radii
  185. // -----------------------------------------
  186.  
  187. LRESULT APIENTRY WndProc4 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  188. {
  189.      static int cxClient, cyClient ;
  190.      HDC        hdc ;
  191.      int        iDiameter ;
  192.      
  193.      switch (message)
  194.      {
  195.      case WM_SIZE:
  196.           cxClient = LOWORD (lParam) ;
  197.           cyClient = HIWORD (lParam) ;
  198.           return 0 ;
  199.           
  200.      case WM_TIMER:
  201.           InvalidateRect (hwnd, NULL, TRUE) ;
  202.           UpdateWindow (hwnd) ;
  203.           
  204.           iDiameter = rand() % (max (1, min (cxClient, cyClient))) ;
  205.           hdc = GetDC (hwnd) ;
  206.           
  207.           Ellipse (hdc, (cxClient - iDiameter) / 2,
  208.                         (cyClient - iDiameter) / 2,
  209.                         (cxClient + iDiameter) / 2,
  210.                         (cyClient + iDiameter) / 2) ;
  211.           
  212.           ReleaseDC (hwnd, hdc) ;
  213.           return 0 ;
  214.      }
  215.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  216. }
  217.  
  218. // -----------------------------------
  219. // Main window to create child windows
  220. // -----------------------------------
  221.  
  222. LRESULT APIENTRY WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  223. {
  224.      static HWND    hwndChild[4] ;
  225.      static TCHAR * szChildClass[] = { TEXT ("Child1"), TEXT ("Child2"),
  226.                                        TEXT ("Child3"), TEXT ("Child4") } ;
  227.      static WNDPROC ChildProc[] = { WndProc1, WndProc2, WndProc3, WndProc4 } ;
  228.      HINSTANCE      hInstance ;
  229.      int            i, cxClient, cyClient ;
  230.      WNDCLASS       wndclass ;
  231.      
  232.      switch (message)
  233.      {
  234.      case WM_CREATE:
  235.           hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
  236.           
  237.           wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  238.           wndclass.cbClsExtra    = 0 ;
  239.           wndclass.cbWndExtra    = 0 ;
  240.           wndclass.hInstance     = hInstance ;
  241.           wndclass.hIcon         = NULL ;
  242.           wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  243.           wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  244.           wndclass.lpszMenuName  = NULL ;
  245.           
  246.           for (i = 0 ; i < 4 ; i++)
  247.           {
  248.                wndclass.lpfnWndProc   = ChildProc[i] ;
  249.                wndclass.lpszClassName = szChildClass[i] ;
  250.                
  251.                RegisterClass (&wndclass) ;
  252.                
  253.                hwndChild[i] = CreateWindow (szChildClass[i], NULL,
  254.                                    WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
  255.                                    0, 0, 0, 0, 
  256.                                    hwnd, (HMENU) i, hInstance, NULL) ;
  257.           }
  258.           
  259.           cyChar = HIWORD (GetDialogBaseUnits ()) ;
  260.           SetTimer (hwnd, 1, 10, NULL) ;
  261.           return 0 ;
  262.           
  263.      case WM_SIZE:
  264.           cxClient = LOWORD (lParam) ;
  265.           cyClient = HIWORD (lParam) ;
  266.           
  267.           for (i = 0 ; i < 4 ; i++)
  268.                MoveWindow (hwndChild[i], (i % 2) * cxClient / 2,
  269.                                          (i > 1) * cyClient / 2,
  270.                            cxClient / 2, cyClient / 2, TRUE) ;
  271.           return 0 ;
  272.           
  273.      case WM_TIMER:
  274.           for (i = 0 ; i < 4 ; i++)
  275.                SendMessage (hwndChild[i], WM_TIMER, wParam, lParam) ;
  276.           
  277.           return 0 ;
  278.           
  279.      case WM_CHAR:
  280.           if (wParam == '\x1B')
  281.                DestroyWindow (hwnd) ;
  282.           
  283.           return 0 ;
  284.           
  285.      case WM_DESTROY:
  286.           KillTimer (hwnd, 1) ;
  287.           PostQuitMessage (0) ;
  288.           return 0 ;
  289.      }
  290.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  291. }
  292.